package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.model.user.UserPaidAlbum;
import com.atguigu.tingshu.model.user.UserPaidTrack;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.mapper.UserPaidAlbumMapper;
import com.atguigu.tingshu.user.mapper.UserPaidTrackMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.album.AlbumTrackListVo;
import com.atguigu.tingshu.vo.album.TrackInfoVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RabbitService rabbitService;

	@Autowired
	private AlbumInfoFeignClient albumInfoFeignClient;

	@Autowired
	private UserPaidAlbumMapper userPaidAlbumMapper;

	@Autowired
	private UserPaidTrackMapper userPaidTrackMapper;
	/**
	 * 微信登录
	 * @param code
	 * @return
	 */
	@Override
	public Map<String, Object> wxLogin(String code) {
		//	调用微信登录api;
		WxMaJscode2SessionResult wxMaJscode2SessionResult = null;
		try {
			wxMaJscode2SessionResult = wxMaService.jsCode2SessionInfo(code);
		} catch (WxErrorException e) {
			throw new RuntimeException(e);
		}
		//	openid: 每个人的微信都对应的一个微信标识！
		String openid = wxMaJscode2SessionResult.getOpenid();
		//	利用openid 实现登录或注册功能;
		UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openid));
		//	判断对象是否为空
		if (null == userInfo) {
			//	说明要注册： 本质赋值;
			userInfo = new UserInfo();
			userInfo.setWxOpenId(openid);
			userInfo.setNickname("听友:" + System.currentTimeMillis());
			userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
			//	保存数据到数据库;
			userInfoMapper.insert(userInfo);
			//  在此需要给当前注册的用户进行初始化充值;  同步：异步：mq 发送消息;
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_USER_REGISTER,userInfo.getId());
		}
		//	说明要登录： 将数据存储到redis，与返回token;
		String token = UUID.randomUUID().toString().replaceAll("-", "");
		//	组成缓存的key;
		String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
		//  存储数据;
		redisTemplate.opsForValue().set(userLoginKey, userInfo, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
		//  返回数据;
		HashMap<String, Object> map = new HashMap<>();
		map.put("token", token);
		return map;
	}

	/**
	 * 获取用户信息
	 * @param userId
	 * @return
	 */
	@Override
	public UserInfoVo getUserInfo(Long userId) {
		// 查询用户信息
		UserInfo userInfo = this.getById(userId);
		// 创建一个目标对象
		UserInfoVo userInfoVo = new UserInfoVo();
		// 属性拷贝
		BeanUtils.copyProperties(userInfo,userInfoVo);
		return userInfoVo;
	}

	/**
	 * 修改用户信息
	 * @param userId
	 * @param userInfoVo
	 */
	@Override
	public void updateUser(Long userId, UserInfoVo userInfoVo) {
		// 修改用户信息
		UserInfo userInfo = new UserInfo();
		// 属性拷贝
		BeanUtils.copyProperties(userInfoVo,userInfo);
		userInfo.setId(userId);
		this.updateById(userInfo);
	}

	/**
	 * 判断用户是否购买声音列表
	 * @param albumId
	 * @param trackIdList
	 * @param userId
	 * @return
	 */
	@Override
	public Map<Long, Integer> userIsPaidTrack(Long albumId, List<Long> trackIdList, Long userId) {
		//  创建map 集合：
		Map<Long, Integer> map = trackIdList.stream().collect(Collectors.toMap(trackId -> trackId, trackId -> 0));
		//  判断用户是否购买过专辑：user_paid_album
		UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
		if (null != userPaidAlbum) {
			//  当前这个用户购买了专辑;
			return trackIdList.stream().collect(Collectors.toMap(trackId -> trackId, trackId -> 1));
		}
		//  查询用户购买声音的集合列表;
		List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getUserId, userId).in(UserPaidTrack::getTrackId, trackIdList));
		//  这个列表; 有可能是空：
		if (!CollectionUtils.isEmpty(userPaidTrackList)) {
			//  购买过声音;
			for (UserPaidTrack userPaidTrack : userPaidTrackList) {
				map.put(userPaidTrack.getTrackId(), 1);
			}
		}
		//  返回数据：
		return map;
	}

	/**
	 * 查看当前用户是否购买过专辑
	 * @param userId
	 * @param albumId
	 * @return
	 */
	@Override
	public Boolean isPaidAlbum(Long userId, Long albumId) {
		//  查看当前用户是否购买过专辑;
		//  先判断用户Id是否相同，再判断专辑Id是否相同; select user_id,id from user_paid_album where user_id=? and album_id = ?;
		return null != userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
	}


	/**
	 * 获取到当前用户购买的声音id列表
	 * @param albumId
	 * @param userId
	 * @return
	 */
	@Override
	public List<Long> findUserPaidTrackList(Long albumId, Long userId) {
		List<UserPaidTrack> userPaidTracks = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getAlbumId, albumId).eq(UserPaidTrack::getUserId, userId));
		List<Long> userPaidTrackIdList = userPaidTracks.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
		return userPaidTrackIdList;
	}


}
